package org.zjvis.datascience.common.graph.importer;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;

/**
 * @description ImporterGML
 * @date 2021-12-29
 */
public class ImporterGML {
    private JSONArray nodes;
    private JSONArray links;

    public ImporterGML() {
        nodes = new JSONArray();
        links = new JSONArray();
    }

    public boolean execute(InputStream in) throws IOException {

        InputStreamReader reader = new InputStreamReader(in, StandardCharsets.UTF_8);


        List<Object> list = this.parseList(reader);
        boolean ret = false;
        for(int i = 0; i < list.size(); ++i) {
            if ("graph".equals(list.get(i)) && list.size() >= i + 2 && list.get(i + 1) instanceof ArrayList) {
                ret = this.parseGraph((ArrayList)list.get(i + 1));
            }
        }
        return ret;
    }

    public static void main(String[] arg) throws IOException {
        ImporterGML importerGML = new ImporterGML();
        File file = new File("D:\\Users\\Lenovo\\Desktop\\图分析数据\\gml测试.gml");
        InputStream in=new FileInputStream(file);
        importerGML.execute(in);
    }

    private ArrayList<Object> parseList(InputStreamReader reader) throws IOException {
        ArrayList<Object> list = new ArrayList<>();
        boolean readString = false;
        String stringBuffer = new String();
        while(true) {
            int rsz = reader.read();
            if (rsz < 0) {
                break;
            }
            char t = (char)rsz;
            if (readString) {
                if (t == '"') {
                    list.add(stringBuffer);
                    stringBuffer = new String();
                    readString = false;
                } else {
                    stringBuffer = stringBuffer + t;
                }
            } else {
                switch(t) {
                    case '\t':
                    case '\n':
                    case ' ':
                        if (!stringBuffer.isEmpty()) {
                            try {
                                Long longValue = Long.valueOf(stringBuffer);
                                list.add(longValue);
                            } catch (NumberFormatException var9) {
                                try {
                                    Double doubleValue = Double.valueOf(stringBuffer);
                                    list.add(doubleValue);
                                } catch (NumberFormatException var8) {
                                    if (stringBuffer.equalsIgnoreCase("true")
                                            || stringBuffer.equalsIgnoreCase("false")) {
                                        Boolean booleanValue = Boolean.valueOf(stringBuffer);
                                        list.add(booleanValue);
                                    } else {
                                        list.add(stringBuffer);
                                    }
                                }
                            }

                            stringBuffer = new String();
                        }
                        break;
                    case '"':
                        readString = true;
                        break;
                    case '[':
                        list.add(this.parseList(reader));
                        break;
                    case ']':
                        return list;
                    default:
                        stringBuffer = stringBuffer + t;
                }
            }
        }

        return list;
    }

    private boolean parseGraph(List<Object> list) {
        if ((list.size() & 1) != 0) {
            return false;
        } else {
            for(int i = 0; i < list.size(); i += 2) {
                Object key = list.get(i);
                Object value = list.get(i + 1);
                if ("node".equals(key)) {
                    JSONObject node = this.parseList((ArrayList)value);
                    nodes.add(node);
                } else if ("link".equals(key)) {
                    JSONObject link = this.parseList((ArrayList)value);
                    links.add(link);
                }
            }
            return true;
        }
    }

    private JSONObject parseList(List<Object> list) {
        JSONObject jo = new JSONObject();
        for(int i = 0; i < list.size(); i += 2) {
            String key = list.get(i).toString();
            Object value = list.get(i + 1);
            if (value instanceof ArrayList) {
                jo.put(key, parseList((ArrayList)value));
            } else {
                jo.put(key, value);
            }
        }
        return jo;
    }

    public JSONArray getNodes() {
        return nodes;
    }

    public JSONArray getLinks() {
        return links;
    }
}
